package frsf.cidisi.exercise.modelo.search.actions;

import frsf.cidisi.exercise.modelo.search.AgenteEstado;
import frsf.cidisi.exercise.modelo.search.AmbienteEstado;
import frsf.cidisi.exercise.modelo.util.Coordenada;
import frsf.cidisi.exercise.modelo.util.Laberinto;
import frsf.cidisi.exercise.modelo.util.Orientacion;
import frsf.cidisi.faia.agent.search.SearchAction;
import frsf.cidisi.faia.agent.search.SearchBasedAgentState;
import frsf.cidisi.faia.state.AgentState;
import frsf.cidisi.faia.state.EnvironmentState;

public class Avanzar extends SearchAction {
	
	private static int tam = 4;

	/**
	 * This method updates a tree node state when the search process is running.
	 * It does not updates the real world state.
	 */
	@Override
	public SearchBasedAgentState execute(SearchBasedAgentState s) {
		AgenteEstado agState = (AgenteEstado) s;

		// Avanzo un casillero si esta permitido
		Coordenada nueva = avanzar(agState.getPosAgente(), agState.getLaberinto(), agState.getOrientacion());
		agState.setposAgente(nueva);

		return agState;
	}

	public Coordenada avanzar(Coordenada posActual, Laberinto laberinto, Orientacion orientacion) {

		switch (orientacion.getValue()) {
		case 1:
			if(!laberinto.getCelda(posActual).getParedNorte() && posActual.getY().intValue() > 0)
				return new Coordenada(posActual.getX().intValue(), posActual.getY().intValue()-1);
			break;

		case 2:
			if(!laberinto.getCelda(posActual).getParedSur() && posActual.getY().intValue() < (tam-1))
				return new Coordenada(posActual.getX().intValue(), posActual.getY().intValue()+1);
			break;

		case 3:
			if(!laberinto.getCelda(posActual).getParedEste() && posActual.getX().intValue() < (tam-1))
				return new Coordenada(posActual.getX().intValue()+1, posActual.getY().intValue());
			break;

		case 4:
			if(!laberinto.getCelda(posActual).getParedOeste() && posActual.getX().intValue() > 0)
				return new Coordenada(posActual.getX().intValue()-1, posActual.getY().intValue());
			break;
		}
		return posActual;
	}

	/**
	 * This method updates the agent state and the real world state.
	 */
	@Override
	public EnvironmentState execute(AgentState ast, EnvironmentState est) {
		AmbienteEstado environmentState = (AmbienteEstado) est;
		AgenteEstado agState = ((AgenteEstado) ast);

		// Avanzo un casillero si esta permitido
		Coordenada nueva = avanzar(agState.getPosAgente(), agState.getLaberinto(), agState.getOrientacion());
		agState.setposAgente(nueva);

		return environmentState;
	}

	/**
	 * This method returns the action cost.
	 */
	@Override
	public Double getCost() {
		return new Double(1);
	}

	/**
	 * This method is not important for a search based agent, but is essensial
	 * when creating a calculus based one.
	 */
	@Override
	public String toString() {
		return "Avanzar";
	}
}